import * as echarts from 'echarts/core';
import type { PieSeriesOption, BarSeriesOption, LineSeriesOption } from "echarts/charts";
import { Dashboard } from "../model/base/dashboard";
import { LayoutGrid } from "../model/base/layout";
import type { GridComponentOption } from 'echarts/types/dist/components';
import { Loglist } from './log';

const pieOptions: echarts.ComposeOption<
    PieSeriesOption | GridComponentOption
> = {
    tooltip: {
        trigger: 'item'
    },
    backgroundColor: 'transparent',
    series: [{
        type: 'pie',
        radius: ['24%', '44%'],
        itemStyle: {
            borderRadius: 6,
            borderWidth: 2
        },
        label: {
            formatter: '{b}:{c}'
        },
        labelLine: {
            length: 4,
            length2: 0
        },
        avoidLabelOverlap: false,
    }]
}
const barOptions: echarts.ComposeOption<
    BarSeriesOption | GridComponentOption
> = {
    grid: { top: '5%', bottom: 24 },
    tooltip: {
        trigger: 'item'
    },
    xAxis: {
        type: 'category'
    },
    yAxis: {
        type: 'value',
        splitLine: {
            show: false
        }
    },
    backgroundColor: 'transparent',
    series: [
        {
            type: 'bar',
            colorBy: "data",
            itemStyle: {
                borderRadius: 6
            },
            label: {
                formatter: '{b}:{c}'
            },
            labelLine: {
                length: 4,
                length2: 0
            },
        }
    ]
};
const lineOptions: echarts.ComposeOption<
    LineSeriesOption | GridComponentOption
> = {
    grid: { top: '5%', bottom: 24 },
    tooltip: {
        trigger: 'item'
    },
    xAxis: {
        type: 'category'
    },
    yAxis: {
        type: 'value',
    },
    backgroundColor: 'transparent',
    series: [
        {
            type: 'line',
            label: {
                formatter: '{b}:{c}'
            },
            labelLine: {
                length: 4,
                length2: 0
            },
        }
    ]
};

export class IndexLayoutGrid extends LayoutGrid {
    data?: interfaceAllChart
    timer: number
    avatar: interfaceAvatar[]
    charts: [UserChart, RoomChart, BlockChart, MenuChart, SuggestChart]
    constructor() {
        super()
        this.timer = 0
        this.avatar = []
        this.setAreas([
            ["header",
                "a",
                "a",
                "b",
                "b",
                "c",
                "c",
                "d",
                "d",
                "e",
                "e",
                "e",
                "e"],
            ["header header b b c c c",
                "a a b b c c c",
                "a a b b c c c",
                "d d d d e e e",
                "d d d d e e e",
                "d d d d e e e"]
        ])
        this.setWidths([500, 1000])
        this.charts = [new UserChart(), new RoomChart(), new BlockChart(), new MenuChart(), new SuggestChart()]
    }
    async getAvatar() {
        const res: interfaceAvatar[] = await this.request('/v1/dashboard/getAvatar')
        this.avatar = res
    }
    async getData() {
        // if (this.timer) clearTimeout(this.timer)
        this.data = await this.request('/v1/dashboard/getDashboardAll')
        this.render()
        // this.timer = setTimeout(() => {
        //     this.getData()
        // }, 5000)
    }
    render() {
        if (!this.data) return
        const { countByUser,
            totalUser,
            totalVisitor,
            countByMenu,
            totalMenu,
            totalRole,
            countBySuggest,
            countByRoom,
            countByBlock } = this.data
        //置空图标数据，用于实现动画效果
        this.charts[0]._setData([], totalUser, totalVisitor)
        this.charts[1]._setData([])
        this.charts[2]._setData([])
        this.charts[3]._setData([], totalMenu, totalRole)
        this.charts[4]._setData([])

        this.charts[0]._setData(countByUser, totalUser, totalVisitor)
        this.charts[1]._setData(countByRoom)
        this.charts[2]._setData(countByBlock)
        this.charts[3]._setData(countByMenu, totalMenu, totalRole)
        this.charts[4]._setData(countBySuggest)
    }
    dispose() {
        if (this.timer) clearTimeout(this.timer)
        this.charts.forEach(chart => {
            requestIdleCallback(() => {
                chart.dispose()
            })
        })
    }
}

export class UserChart extends Dashboard {
    total: number
    totalvisitor: number
    constructor() {
        super()
        this.total = 0
        this.totalvisitor = 0
        this.options = pieOptions
        this.delay = 4000
    }

    async _setData(countByUser: { Area_name: string, count: number }[], userTotal: number, visitorTotal: number) {
        this.total = userTotal
        this.totalvisitor = visitorTotal
        if (this.chart?.isDisposed()) return
        this.chart?.setOption({
            series: [{
                data: countByUser.map(item => ({ name: item.Area_name || '未知', value: item.count }))
            }]
        })
    }
    async setData(cache: 'cache' | 'recache' = 'cache') {
        const res: interfaceAreaChart = await this.request('/v1/dashboard/getUserByArea', { cache })
        if (res) {
            const countByArea_name = res.countByArea_name
            const userTotal = res.total
            const visitorTotal = res.totalvisitor
            this._setData(countByArea_name, userTotal, visitorTotal)
        }
    }
}

export class RoomChart extends Dashboard {
    constructor() {
        super()
        this.options = pieOptions
        this.delay = 4000
    }

    _setData(countByRoom: { Area_name: string, count: number }[]) {
        if (this.chart?.isDisposed()) return
        this.chart?.setOption({
            series: [{
                data: countByRoom.map(item => ({ name: item.Area_name || '未知', value: item.count }))
            }]
        })
    }
    async setData(cache: 'cache' | 'recache' = 'cache') {
        const res: interfaceAreaChart = await this.request('/v1/dashboard/getRoomByArea', { cache })
        const countByArea_name = res.countByArea_name
        this._setData(countByArea_name)
    }
}

export class BlockChart extends Dashboard {
    constructor() {
        super()
        this.options = pieOptions
        this.delay = 4000
    }

    _setData(countByBlock: { Area_name: string, count: number }[]) {
        if (this.chart?.isDisposed()) return
        this.chart?.setOption({
            series: [{
                data: countByBlock.map(item => ({ name: item.Area_name || '未知', value: item.count }))
            }]
        })
    }
    async setData(cache: 'cache' | 'recache' = 'cache') {
        const res: interfaceAreaChart = await this.request('/v1/dashboard/getBlockByArea', { cache })
        if (res) {
            const countByArea_name = res.countByArea_name
            this._setData(countByArea_name)
        }
    }
}

export class MenuChart extends Dashboard {
    total: number
    roleTotal: number
    constructor() {
        super()
        this.total = 0
        this.roleTotal = 0
        this.options = barOptions
        this.delay = 4000
    }

    _setData(countByMenu: { type: number, count: number }[], totalMenu: number, totalRole: number) {
        if (this.chart?.isDisposed()) return
        const types = ["", "菜单", "路径", "按钮"]
        this.total = totalMenu
        this.roleTotal = totalRole
        const _countByMenu = countByMenu.map(item => ({ name: types[item.type], count: item.count }))
        this.chart?.setOption({
            xAxis: {
                data: _countByMenu.map(item => item.name)
            },
            series: [{
                data: _countByMenu.map(item => ({ name: item.name, value: item.count }))
            }]
        })

    }
    async setData(cache: 'cache' | 'recache' = 'cache') {
        const res: interfaceMenuTypeChart = await this.request('/v1/dashboard/getMenuByType', { cache })
        this._setData(res.countByType, res.total, res.roleTotal)
    }
}

export class SuggestChart extends Dashboard {
    constructor() {
        super()
        this.options = lineOptions
        this.delay = 4000
    }
    _setData(countByTime: { created_at: string, count: number }[]) {
        if (this.chart?.isDisposed()) return
        this.chart?.setOption({
            xAxis: {
                data: countByTime.map(item => item.created_at)
            },
            series: [{
                data: countByTime.map(item => ({ name: item.created_at, value: item.count }))
            }]
        })
    }
    async setData(cache: 'cache' | 'recache' = 'cache') {
        const res: interfaceTimeChart = await this.request('/v1/dashboard/getSuggestByTime', { cache })
        this._setData(res.countByTime)
    }
}

export class LogChart extends Loglist {
    constructor() {
        super()
        this.disabledRefresh = true
        this.limit = 5
        this.url.page = '/v1/dashboard/getLogByToday'
        this.select = undefined
        this.actions = undefined
        this.immediateCheck = true
    }
}